1 00:00:00,870 --> 00:00:05,430 Alrighty, in this lecture, we're going to be creating a leaderboard that is going to keep track of 2 00:00:05,430 --> 00:00:08,340 the stages and deaths for all players in a server. 3 00:00:08,340 --> 00:00:13,290 Tracking deaths is going to be easy, but since the Abi is generated on the client, we'll have to use 4 00:00:13,290 --> 00:00:17,670 our remote event to let the server know when we have touched a new checkpoint, and then the server 5 00:00:17,670 --> 00:00:22,830 will have to do some sanity checks to make sure that the remote event isn't being fired too fast. 6 00:00:23,430 --> 00:00:28,800 Now we can let the server know when we've touched new checkpoint by going to our RB generation handler. 7 00:00:30,640 --> 00:00:35,050 And when we go, when we touch a new checkpoint, what we could do is we could fire that remote event 8 00:00:35,050 --> 00:00:40,360 to let the server know that we would like to increment our stage to the next stage that we are at. 9 00:00:40,810 --> 00:00:43,630 So we can go ahead and get this event. 10 00:00:43,990 --> 00:00:48,670 And I'm just going to call it leader board Comms event. 11 00:00:48,670 --> 00:00:54,730 And this event is located in Replicated storage and the events folder and it's called Leaderboard comms. 12 00:00:55,270 --> 00:00:59,290 And then we can use this event to fire to the server to do a specific action. 13 00:00:59,320 --> 00:01:04,480 Now a way for us to keep track of all of the actions that we can have the server perform. 14 00:01:04,480 --> 00:01:09,340 What we could do is we could go into replicated storage, and in our modules folder we can create a 15 00:01:09,340 --> 00:01:11,500 new module script underneath the enums folder. 16 00:01:11,500 --> 00:01:15,040 And this module script in here is going to act as a custom enum. 17 00:01:15,040 --> 00:01:19,600 So we can call this our leaderboard comms enum. 18 00:01:20,300 --> 00:01:23,390 And inside of here we can just call a table self. 19 00:01:24,060 --> 00:01:28,080 And we'll make sure to return self at the end of this module. 20 00:01:28,080 --> 00:01:35,070 And inside of this table is where we're going to store basically the enums for different actions. 21 00:01:35,070 --> 00:01:39,780 Now I can specify which actions belong to the server or to the client. 22 00:01:39,780 --> 00:01:42,420 And I'll create a key in here called to server. 23 00:01:42,420 --> 00:01:43,950 And we'll store a table. 24 00:01:43,950 --> 00:01:47,100 And inside of this table is where we can store all of our different actions. 25 00:01:47,100 --> 00:01:52,770 So for example when I touch a new checkpoint I want to tell the server to increment what stage I'm at 26 00:01:52,770 --> 00:02:00,420 so I can call this action increment stage and just set it equal to a string that says increment stage. 27 00:02:00,420 --> 00:02:03,630 So this is like my pseudo enum basically. 28 00:02:04,190 --> 00:02:06,170 And then I can go ahead and require this enum. 29 00:02:06,170 --> 00:02:13,610 I'll call it leaderboard comms enum and we'll require from replicated storage, dot modules, dot enums, 30 00:02:13,610 --> 00:02:15,530 dot leaderboard comms enum. 31 00:02:15,530 --> 00:02:21,080 And that way when we touch a checkpoint model, we can go ahead and use the leaderboard comms event 32 00:02:21,080 --> 00:02:28,040 and fire to the server and give it the action of our leaderboard comms enum dot two server dot increment 33 00:02:28,040 --> 00:02:28,970 stage. 34 00:02:29,480 --> 00:02:34,910 And since we're returning once the checkpoint model is set to whatever model was touched, that means 35 00:02:34,910 --> 00:02:38,030 we're only going to fire this event once per stage. 36 00:02:38,880 --> 00:02:40,770 Now to set up the leaderboard on the server. 37 00:02:40,770 --> 00:02:47,070 What we can do is open up server script service and add a new service in here, or a new module script. 38 00:02:47,070 --> 00:02:50,910 And I'm going to call this my leaderboard service. 39 00:02:51,930 --> 00:02:58,350 And I'm going to use that template we've been using previously, and I'm going to rename it to Leader 40 00:02:58,350 --> 00:02:59,970 Board Service. 41 00:03:00,580 --> 00:03:03,880 And inside of here, we're going to need the player service. 42 00:03:04,870 --> 00:03:07,240 As well as replicated storage. 43 00:03:09,810 --> 00:03:13,500 And then we can go ahead and refer to that same event, which is our leaderboard. 44 00:03:15,420 --> 00:03:20,070 Com's event and replicated storage dot events, dot leaderboard coms. 45 00:03:20,070 --> 00:03:21,750 And then we'll get the exact same enum. 46 00:03:21,750 --> 00:03:29,370 So leader board comms enum require replicated storage dot modules dot enums dot leaderboard comms enum. 47 00:03:30,310 --> 00:03:35,950 And to make sure that the players don't fire this event too quickly, we can go ahead and create a table. 48 00:03:35,950 --> 00:03:38,650 I'll call it player time stamps. 49 00:03:40,280 --> 00:03:43,910 And this will keep track of whenever the player last fired this event. 50 00:03:43,910 --> 00:03:49,280 And if they're firing it too quickly, then we can basically mark up some warnings for this player. 51 00:03:49,280 --> 00:03:53,960 And then once their warnings exceeds a certain threshold, then we can kick the player out of the game 52 00:03:53,960 --> 00:03:55,400 because they might be cheating. 53 00:03:55,400 --> 00:03:56,750 So we'll create another table. 54 00:03:56,750 --> 00:04:02,780 I'll call it player warn counts, and that's where we'll store warnings for each player. 55 00:04:02,780 --> 00:04:05,180 And then we can go ahead and define those thresholds. 56 00:04:05,180 --> 00:04:11,120 Here I'll call this, um, my warn count threshold. 57 00:04:11,120 --> 00:04:15,680 So once they get above let's say five warnings, then we'll kick them from the game. 58 00:04:15,680 --> 00:04:22,160 And then we also want to define a constant that's going to be the threshold for the time duration between 59 00:04:22,160 --> 00:04:23,510 events being fired. 60 00:04:23,510 --> 00:04:26,780 So I'll call it event uh threshold. 61 00:04:26,780 --> 00:04:28,880 And I'll set it to something like one second. 62 00:04:28,880 --> 00:04:34,070 So if the client is firing this event faster than one second, that means they might be cheating and 63 00:04:34,070 --> 00:04:36,950 firing this remote event, or they might be flying through the map or whatever. 64 00:04:36,950 --> 00:04:39,500 We want to set a warning for them. 65 00:04:39,680 --> 00:04:39,980 Now. 66 00:04:39,980 --> 00:04:43,310 The service, of course, needs to set up a leaderboard for every single player in our game. 67 00:04:43,310 --> 00:04:44,930 So we'll create a function for doing that. 68 00:04:44,930 --> 00:04:51,140 We'll call it Setup Leader stats for and we'll pass a player to this function. 69 00:04:52,890 --> 00:04:56,280 And also have a function to listen for when a player's character dies. 70 00:04:56,280 --> 00:05:02,100 So we'll call it on character death, and we'll pass a player instance to this to get. 71 00:05:03,140 --> 00:05:08,300 Which player's character died, and then from there we would increment the death value in their leader 72 00:05:08,300 --> 00:05:09,020 stats. 73 00:05:10,550 --> 00:05:15,020 So in this initialized section, what we want to do is we want to listen to the players that player 74 00:05:15,020 --> 00:05:19,190 added event and connect a function to this and get that player. 75 00:05:20,800 --> 00:05:23,410 We can go ahead and set up the lidar stats for that player. 76 00:05:23,410 --> 00:05:27,130 And then we would also want to listen for when a character is added to this player. 77 00:05:29,380 --> 00:05:32,410 Look at that character, and then we want to listen for when that character dies. 78 00:05:32,410 --> 00:05:37,570 So we'll refer to the character humanoid died event connect a function. 79 00:05:37,570 --> 00:05:40,540 And this is where we would call our on character death. 80 00:05:42,170 --> 00:05:46,400 And this is where we would call our on character death and pass the player. 81 00:05:47,030 --> 00:05:53,600 And then we also want to loop through every single player in the game, get players. 82 00:05:54,960 --> 00:05:59,010 And we're basically just going to do the exact same thing, set up the leader stats for this player, 83 00:05:59,010 --> 00:06:03,000 and then just basically copy that, paste that in there and we should be good to go. 84 00:06:03,710 --> 00:06:08,630 One last thing we can go ahead and check for when we're testing in studio is that this might execute 85 00:06:08,630 --> 00:06:14,210 after the player already had a character added to them, so we can add an if statement to quickly check 86 00:06:14,210 --> 00:06:16,070 if they already have a character. 87 00:06:17,360 --> 00:06:19,730 So I'll just copy this here. 88 00:06:20,690 --> 00:06:23,600 And then change this to player character. 89 00:06:24,270 --> 00:06:29,640 And then afterwards we want to go ahead and connect to that remote event that's in replicated storage. 90 00:06:29,640 --> 00:06:36,540 So leaderboard comms event we want to listen to on server event connect a function to this. 91 00:06:36,540 --> 00:06:41,100 And we're going to be given the player that fired this event as well as the action they would like us 92 00:06:41,100 --> 00:06:41,940 to do. 93 00:06:42,240 --> 00:06:45,600 And we can go ahead and check if this action is equal to our leaderboard. 94 00:06:45,600 --> 00:06:49,200 Comms enum dot two server dot increment stage. 95 00:06:49,770 --> 00:06:56,040 If it is, then this is where we're going to want to check, um the timestamp for this player. 96 00:06:56,040 --> 00:07:01,920 Now when this event gets fired, we want to make sure we go ahead and add a key to our timestamp table. 97 00:07:01,920 --> 00:07:07,830 So if this player does not have a timestamp in our player timestamps table, we'll use their name as 98 00:07:07,830 --> 00:07:08,370 the key. 99 00:07:08,370 --> 00:07:10,140 Then we'll go ahead and set it up for them. 100 00:07:10,140 --> 00:07:13,410 We'll do player timestamps player dot name. 101 00:07:13,410 --> 00:07:18,150 We'll set it equal to the current tech and subtract that by our event threshold. 102 00:07:18,150 --> 00:07:23,190 So that way we don't accidentally flag them when we first set up this table for them. 103 00:07:23,910 --> 00:07:28,980 And then if the action they have us do is going to be incrementing their stage, then we'll check the 104 00:07:28,980 --> 00:07:33,300 current tick and subtract it by whenever they fired this event last. 105 00:07:33,300 --> 00:07:34,860 So we'll just copy this. 106 00:07:35,800 --> 00:07:39,400 And if them firing this event is faster than the event threshold. 107 00:07:39,400 --> 00:07:46,900 So if it's less than the event threshold, then what we want to do is we want to check if they have 108 00:07:46,900 --> 00:07:48,610 a key inside of the player. 109 00:07:48,610 --> 00:07:49,300 One counts. 110 00:07:49,300 --> 00:07:50,620 If they don't, we need to set it up. 111 00:07:50,620 --> 00:07:56,500 So if not player one counts, pass their name, then we'll go ahead and set it up for them. 112 00:07:56,500 --> 00:08:00,250 So we'll copy this and set it equal to one. 113 00:08:00,960 --> 00:08:07,140 Otherwise, we'll go ahead and copy this and then increment the value that's already there by one. 114 00:08:09,310 --> 00:08:16,150 And then if they're player one counts for this particular player exceeds the threshold we set. 115 00:08:16,150 --> 00:08:21,220 So if this becomes greater than our one count threshold then we need to kick the player. 116 00:08:21,220 --> 00:08:28,090 So player kick we'll just say unusual client behavior detected. 117 00:08:29,400 --> 00:08:31,980 Otherwise we could give a warning in the console. 118 00:08:31,980 --> 00:08:34,830 We could say something like, uh, user. 119 00:08:35,960 --> 00:08:38,570 We'll say player name. 120 00:08:39,660 --> 00:08:42,300 Fired the remote event. 121 00:08:43,160 --> 00:08:47,150 Uh, I will just say leader board comms. 122 00:08:47,150 --> 00:08:48,200 Eventname. 123 00:08:48,200 --> 00:08:51,860 They fired this remote event two fast. 124 00:08:52,620 --> 00:09:00,990 Otherwise, we can go ahead and set player timestamps for this player equal to the current tick. 125 00:09:01,770 --> 00:09:04,500 And then we would update the value in their leader stats. 126 00:09:04,500 --> 00:09:07,950 So let's go ahead and set up the leader stat function. 127 00:09:08,250 --> 00:09:11,430 Inside of here we'll create a new folder for our leader stats. 128 00:09:11,430 --> 00:09:15,060 So instance dot new folder. 129 00:09:17,680 --> 00:09:24,400 Leaderstats dot name equal to Leaderstats Leaderstats dot parent equal to our player. 130 00:09:24,490 --> 00:09:27,280 And then we'll go ahead and create some int values. 131 00:09:27,280 --> 00:09:31,600 I'll call this one stage instance dot new int value. 132 00:09:32,450 --> 00:09:35,600 Stage name is going to be equal to stage. 133 00:09:36,690 --> 00:09:38,940 And then stage that value is going to be zero. 134 00:09:38,940 --> 00:09:42,240 And then stage dot parent is going to be equal to liter stats. 135 00:09:42,240 --> 00:09:46,200 And then we can just copy this and do the exact same thing. 136 00:09:46,200 --> 00:09:48,600 But instead we're going to do it for our deaths. 137 00:09:49,080 --> 00:09:51,360 So we'll rename this to deaths. 138 00:09:51,570 --> 00:09:53,730 Change the name here to deaths. 139 00:09:54,060 --> 00:09:55,080 And there we go. 140 00:09:55,080 --> 00:09:57,120 We'll set up a liter stat for that player. 141 00:09:57,810 --> 00:10:04,800 And then when their player dies we'll refer to this players liter stats folder, get their deaths in 142 00:10:04,800 --> 00:10:08,520 value and set the value plus equal to one. 143 00:10:08,520 --> 00:10:10,860 And then we do the same thing down here. 144 00:10:10,860 --> 00:10:14,310 We're going to refer to the player dot liter stats. 145 00:10:14,310 --> 00:10:15,990 Get their stage. 146 00:10:15,990 --> 00:10:18,960 Set the value plus equal to one. 147 00:10:20,050 --> 00:10:24,280 And we're not going to need a start function for the service, so we'll get rid of that. 148 00:10:24,850 --> 00:10:30,040 And the one last thing I'm going to add is I'm going to listen to the players player removing event, 149 00:10:30,040 --> 00:10:32,140 connect a function and get that player. 150 00:10:32,960 --> 00:10:35,630 That's because we want to go ahead and clear up any memory. 151 00:10:35,630 --> 00:10:40,220 If this player is stored in the player's timestamps table, or if they're played in the player worn 152 00:10:40,220 --> 00:10:41,120 count table. 153 00:10:41,120 --> 00:10:48,890 So we'll set player timestamps for this particular player equal to nil, as well as for the player worn 154 00:10:48,890 --> 00:10:49,790 counts. 155 00:10:50,690 --> 00:10:53,900 We'll get that player and set that equal to nil. 156 00:10:55,240 --> 00:10:58,510 And I think we've got everything set up for our leaderboard. 157 00:10:58,510 --> 00:11:03,130 So now any time our player dies, we're going to increment their leader stats. 158 00:11:03,130 --> 00:11:08,620 And then any time the player fires that event to us we're going to increment their stage. 159 00:11:08,920 --> 00:11:10,540 So let's go ahead and try it out. 160 00:11:11,050 --> 00:11:13,540 If we go and play test the game here there's our leader stats. 161 00:11:13,540 --> 00:11:15,580 If we touch the first stage there we are. 162 00:11:15,610 --> 00:11:19,000 We're on stage one I got blown up by a landmine. 163 00:11:19,210 --> 00:11:22,060 So there's a hidden trap right there. 164 00:11:22,060 --> 00:11:23,950 Let me make sure not to touch those stuff. 165 00:11:26,120 --> 00:11:31,370 And we're currently incrementing stages are going up and it also incremented our death there. 166 00:11:31,370 --> 00:11:32,420 So that's cool. 167 00:11:33,230 --> 00:11:34,940 And we'll just keep walking along. 168 00:11:34,940 --> 00:11:36,200 Oh there's a shotgun trap. 169 00:11:36,200 --> 00:11:38,720 So and there's another landmine. 170 00:11:39,610 --> 00:11:42,220 But deaths are working. 171 00:11:42,220 --> 00:11:44,530 Stage increment is working. 172 00:11:44,530 --> 00:11:45,970 If I go and die again. 173 00:11:46,720 --> 00:11:47,320 There we go. 174 00:11:47,320 --> 00:11:48,730 Deaths get incremented. 175 00:11:48,730 --> 00:11:49,810 Very cool. 176 00:11:51,290 --> 00:11:53,300 We are nearly done with this project. 177 00:11:53,300 --> 00:11:57,980 The last thing we're going to add is a day time cycle, and we'll do that in the next lecture. 178 00:11:57,980 --> 00:11:59,030 See you there.